﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        private Values values;
        private SerialCommunication serialComm;
        private object valueLock;
        private Thread serialThread;

        public Form1()
        {
            InitializeComponent();
            values = new Values();
            serialComm = new SerialCommunication(ref values);
            valueLock = new object();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            values.currentPower = powersliderBar.Value;
            values.desiredPower = powersliderBar.Value;

            powerBarLabel.Text = powersliderBar.Value + "";
            timeLabel.Text = values.stopwatch.Elapsed.ToString().Substring(0, 8) + "";
            heartbeatLabel.Text = "Heart BPM: " + values.heartbeat + "";
            rpmLabel.Text = "RPM: " + values.rpm + "";
            speedLabel.Text = "Speed: " + values.speed + "";
            distanceLabel.Text = "Distance: " + values.distance * 100 + "";
            desiredpowerLabel.Text = "Desired Power: " + values.desiredPower + "";
            energyLabel.Text = "Energy: " + values.energy + "";
            currentpowerLabel.Text = "Current Power: " + values.currentPower + "";

            serialThread = new Thread(new ThreadStart(serialComm.Run));
            serialThread.IsBackground = true;
            serialThread.Start();

            System.Windows.Forms.Timer updateTimer = new System.Windows.Forms.Timer();
            updateTimer.Tick += new EventHandler(Update);
            updateTimer.Interval = 100;
            updateTimer.Start();
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            serialComm.Stop();
            serialThread.Abort();   // Maybe this can be harmful because it force-aborts the thread?
        }

        private void Update(Object myObject, EventArgs myEventArgs)
        {
            lock (valueLock)
            {
                if (values.stopwatch.IsRunning)
                {
                    if (values.currentPower < values.desiredPower)
                        values.currentPower += 5;
                    else if (values.currentPower > values.desiredPower)
                        values.currentPower -= 5;
                }

                // Improvised functions, should be improved I guess.
                if (values.stopwatch.IsRunning)
                {
                    values.energy += values.currentPower / 600f;
                    values.heartbeat = 120 + (int)(values.currentPower / 10);
                    values.rpm = 90 - (int)(values.currentPower / 6);
                    values.speed = (int)((values.rpm * values.currentPower) / 30);
                    values.distance += values.speed / 108000f;
                }

                if (values.setTimeSeconds != 0 && values.stopwatch.Elapsed.TotalSeconds < values.setTimeSeconds)
                    timeLabel.Text = "Remaining time: " + (values.setTimeSeconds - values.stopwatch.Elapsed.TotalSeconds) + " seconds";
                else
                    timeLabel.Text = values.stopwatch.Elapsed.ToString().Substring(0, 8) + "";

                heartbeatLabel.Text = "Heart BPM: " + values.heartbeat;
                rpmLabel.Text = "RPM: " + values.rpm;
                //speedLabel.Text = "Speed: " + values.speed + " /10 km/h";
                speedLabel.Text = "Speed: " + values.speed.ToString().Substring(0, values.speed.ToString().Length - 1) + "," + values.speed.ToString().Substring(values.speed.ToString().Length - 1) + " km/h";
                distanceLabel.Text = "Distance: " + values.distance + " km";
                //distanceLabel.Text = "Distance: " + values.distance.ToString().Substring(0, 2) + " km";
                desiredpowerLabel.Text = "Desired Power: " + values.desiredPower;
                energyLabel.Text = "Energy: " + values.energy + " kJ";
                //energyLabel.Text = "Energy: " + values.energy.ToString().Substring(0, 2) + " kJ";
                currentpowerLabel.Text = "Current Power: " + values.currentPower;

                // Change value of slider to the value that's been given by the other program. (PW# command)!!!
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // IF TIME IS SET THROUGH THE DESKTOP PROGRAM -> COUNT BACKWARDS!
            if (!values.stopwatch.IsRunning)
            {
                values.stopwatch.Start();
                button1.Text = "Stop";
            }
            else
            {
                values.stopwatch.Stop();
                button1.Text = "Start";
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            values.desiredPower = powersliderBar.Value;
        }

        private void powersliderBar_Scroll(object sender, EventArgs e)
        {
            // Make sure the slider only works with increments of 5...
            if (powersliderBar.Value % 5 != 0)
                powersliderBar.Value -= powersliderBar.Value % 5;

            powerBarLabel.Text = powersliderBar.Value + "";
        }

        private void button3_Click(object sender, EventArgs e)
        {
            values.Reset();
            button1.Text = "Start";
            serialComm.Reset();
            powersliderBar.Value = 25;
            powerBarLabel.Text = powersliderBar.Value + "";
            values.currentPower = powersliderBar.Value;
            values.desiredPower = powersliderBar.Value;
        }
    }
}
